package service

import (
	"context"
	"mini-app/config/mysql"
	"mini-app/internal/app/grpc/client"
	"mini-app/internal/app/grpc/common"
	"mini-app/internal/app/grpc/protoc/sale_adminc"
	"mini-app/internal/app/grpc/protoc/system_admin"
	"mini-app/internal/dal"
	"mini-app/internal/dao"
	"strings"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"gorm.io/gorm"
)

type GoodsReview struct{}

// List 评测列表
func (GoodsReview) List(
	ctx context.Context,
	goodsType int,          // 商品类型
	goodsName string,       // 商品名称
	visible int,            //可见 1-显示 2-隐藏
	auditStatus int,        // 审核状态 1-通过 2-拒绝
	startTime, endTime int, // 开始时间-结束时
	page, limit int,
) (records []dao.GoodsReviewListT, total int64, err error) {
	if page == 0 {
		page = 1
	}
	if limit == 0 {
		limit = 20
	}
	records, total = dao.GoodsReview{}.List(
		ctx,
		mysql.NewDB(),
		"", "",
		0, "", 0, auditStatus,
		1,
		startTime, endTime,
		page, limit,
	)
	for index, record := range records {
		userDetail, _ := dao.User{}.UserInfo(ctx, dal.Q, record.OpenID, "", "")
		if userDetail != nil {
			records[index].WechatName = userDetail.NickName
			records[index].WeChatAvatar = userDetail.Image
		}
	}
	saleAdminClient, saleAdminClientErr := client.GetSaleAdminClient()
	if saleAdminClientErr != nil {
		logx.Error(ctx, "connect sale admin grpc error", logx.Any("saleAdminClientErr", saleAdminClientErr))
		return []dao.GoodsReviewListT{}, 0, errorx.New("获取商品信息失败", -1)
	}
	for index, record := range records {
		rsp, err := saleAdminClient.GoodsDetail(ctx, &sale_adminc.GoodsDetailReq{GoodsId: record.GoodsID})
		if err == nil && rsp.GoodsId != "" {
			records[index].GoodsName = rsp.GoodsName
			records[index].GoodsType = int(rsp.GoodsType)
			records[index].GoodsImage = rsp.GoodsImage
			records[index].ReviewPoints = int(rsp.ReviewPoints)
		}
	}
	if len(records) == 0 {
		records = []dao.GoodsReviewListT{}
	}
	return records, total, nil
}

// Audit 评测审核
// reviewID 评测id
// status 审核状态
// visible 是否显示
func (GoodsReview) Audit(ctx context.Context, reviewID string, status int, reason string, auditUserID string) error {
	// 获取评测详情
	reviewDetail := dao.GoodsReview{}.Detail(ctx, mysql.NewDB(), reviewID)
	if reviewDetail == nil {
		return errorx.New("评测不存在", -1)
	}
	// 获取商品详情
	saleAdminClient, saleAdminClientErr := client.GetSaleAdminClient()
	if saleAdminClientErr != nil {
		logx.Error(ctx, "connect sale admin grpc error", logx.Any("saleAdminClientErr", saleAdminClientErr))
		return errorx.New("获取商品信息失败", -1)
	}
	rsp, _ := saleAdminClient.GoodsDetail(ctx, &sale_adminc.GoodsDetailReq{GoodsId: reviewDetail.GoodsID})
	if rsp.GoodsId == "" {
		return errorx.New("商品不存在", -1)
	}
	// 审核
	db := mysql.NewDB()
	err := db.Transaction(func(tx *gorm.DB) error {
		visible := 2
		if status == 1 {
			visible = 1
		}
		success := dao.GoodsReview{}.Audit(ctx, tx, reviewID, status, reason, visible, auditUserID)
		if !success {
			return errorx.New("审核失败", -1)
		}
		if status == 1 {
			if rsp.ReviewPoints > 0 {
				// 审核成功，增加积分
				err := dao.User{}.AddPoints(ctx, dal.Use(tx), reviewDetail.OpenID, int64(rsp.ReviewPoints))
				if err != nil {
					return errorx.New("用户积分增加失败", -1)
				}
			}
		}
		return nil
	})
	return err
}

// Audit 评测显示设置
// reviewIDs 评测id，多个逗号分隔
func (GoodsReview) SetVisible(ctx context.Context, reviewIDs string, visible int) error {
	if reviewIDs == "" {
		return errorx.New("先选中评测", -1)
	}
	reviewIDArr := strings.Split(reviewIDs, ",")
	success := dao.GoodsReview{}.SetVisible(ctx, mysql.NewDB(), reviewIDArr, visible)
	if !success {
		return errorx.New("内容未更新", -1)
	}
	return nil
}

func (GoodsReview) AuditLog(
	ctx context.Context,
	goodsType int,          // 商品类型
	goodsName string,       // 商品名称
	auditStatus int,        // 审核状态
	startTime, endTime int, // 开始时间-结束时间
	page, limit int,        // 分页
) (records []dao.GoodsReviewListT, total int64, err error) {
	if page == 0 {
		page = 1
	}
	if limit == 0 {
		limit = 20
	}
	records, total = dao.GoodsReview{}.AuditLog(ctx, mysql.NewDB(), goodsType, goodsName, auditStatus, startTime, endTime, page, limit)
	for index, record := range records {
		userDetail, _ := dao.User{}.UserInfo(ctx, dal.Q, record.OpenID, "", "")
		if userDetail != nil {
			records[index].WechatName = userDetail.NickName
			records[index].WeChatAvatar = userDetail.Image
		}
	}
	// 商品信息
	saleAdminClient, saleAdminClientErr := client.GetSaleAdminClient()
	if saleAdminClientErr != nil {
		logx.Error(ctx, "connect sale admin grpc error", logx.Any("saleAdminClientErr", saleAdminClientErr))
		return []dao.GoodsReviewListT{}, 0, errorx.New("获取商品信息失败", -1)
	}
	for index, record := range records {
		rsp, err := saleAdminClient.GoodsDetail(ctx, &sale_adminc.GoodsDetailReq{GoodsId: record.GoodsID})
		if err == nil && rsp.GoodsId != "" {
			records[index].GoodsName = rsp.GoodsName
			records[index].GoodsType = int(rsp.GoodsType)
			records[index].GoodsImage = rsp.GoodsImage
			records[index].ReviewPoints = int(rsp.ReviewPoints)
		}
	}
	// 审核人
	auditUserIDs := []string{}
	usernameMap := map[string]string{}
	for _, record := range records {
		auditUserIDs = append(auditUserIDs, record.AuditUserID)
		rsp := common.GRPC{}.UserName(ctx, auditUserIDs)
		usernameMap = rsp.UserNameMap
	}
	for index, record := range records {
		records[index].AuditUser = usernameMap[record.AuditUserID]
	}

	if len(records) == 0 {
		records = []dao.GoodsReviewListT{}
	}
	return
}

func (GoodsReview) Update(
	ctx context.Context,
	openid string,
	id string,
	star string,
	content string,
	images string,
) error {
	detail := dao.GoodsReview{}.Detail(ctx, mysql.NewDB(), id)
	if detail == nil {
		return errorx.New("评测不存在", -1)
	}

	oldImages := helper.SplitComma(detail.Images)
	imagesTemp := images
	newImages := helper.SplitComma(images)
	// 保存新的图片
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		return errorx.New("图片保存失败", -1)
	}
	for _, imageURL := range newImages {
		if !strings.Contains(detail.Images, imageURL) {
			//文件确认
			res, err1 := SystemAdminClient.ConfirmFile(context.Background(), &system_admin.ConfirmFileReq{
				FileUrl: imageURL,
			})
			if err1 != nil && res.Code != 0 {
				logx.Error(context.Background(), "confirm file error", logx.Any("res", res), logx.Any("err", err1.Error()))
				return errorx.New("图片保存失败", -1)
			}
			images = strings.Replace(images, imageURL, res.FileUrl, 1)
		}
	}
	// 删除旧的图片
	for _, imageURL := range oldImages {
		if !strings.Contains(imagesTemp, imageURL) {
			SystemAdminClient.DeleteFile(context.Background(), &system_admin.DeleteFileReq{
				FileUrl: imageURL,
			})
		}
	}

	success := dao.GoodsReview{}.Update(ctx, mysql.NewDB(), openid, id, star, content, images)
	if !success {
		return errorx.New("评测修改失败", -1)
	}
	return nil
}
